package org.oslims.server.service.impl;

import java.util.List;

import net.sf.gilead.gwt.PersistentRemoteService;

import org.hibernate.Session;
import org.oslims.client.service.ParameterResultService;
import org.oslims.domain.ParameterResult;
import org.oslims.server.Util.StateHelper;
import org.oslims.server.dao.AbstractSampleDao;
import org.oslims.server.dao.AnalysisResultDao;
import org.oslims.server.dao.ParameterResultDao;
import org.oslims.server.dao.hbm.HbmAbstractSampleDao;
import org.oslims.server.dao.hbm.HbmAnalysisResultDao;
import org.oslims.server.dao.hbm.HbmParameterResultDao;
import org.oslims.server.dao.util.HibernateUtil;

public class ParameterResultServiceImpl extends PersistentRemoteService implements ParameterResultService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5055518261633155051L;

	private ParameterResultDao parameterResultDao;
	private AnalysisResultDao analysisResultDao;
	private AbstractSampleDao abstractSampleDao;

	public ParameterResultServiceImpl() {

		parameterResultDao = new HbmParameterResultDao();
		analysisResultDao = new HbmAnalysisResultDao();
		abstractSampleDao = new HbmAbstractSampleDao();
	}

	@Override
	public void saveOrUpdateParameterResult(ParameterResult result) {

		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		try {
			parameterResultDao.setSession(session);
			analysisResultDao.setSession(session);
			abstractSampleDao.setSession(session);

			parameterResultDao.makePersistent(result);

			// Manage state transitions
			// Get the possible lower states
			List<String> lowerStates = StateHelper.getLowerStates(result.getState());

			// Check if we can elevate the state of the analysis
			List<String> analysisStates = parameterResultDao.getParameterResultStatesForAnalysis(result.getAnalysisResult().getId());

			Boolean inLowerState = false;

			for (String s : lowerStates) {
				if (analysisStates.contains(s)) {
					inLowerState = true;
					break;
				}
			}

			if (!inLowerState) {
				// Yes we can
				result.getAnalysisResult().setState(result.getState());
				analysisResultDao.makePersistent(result.getAnalysisResult());

				// Check if we can also elevate the state of the sample
				analysisStates = analysisResultDao.getAnalysisStatesForSample(result.getAnalysisResult().getSample().getCode());

				for (String s : lowerStates) {
					if (analysisStates.contains(s)) {
						inLowerState = true;
						break;
					}
				}

				if (!inLowerState) {
					// Yes we can
					result.getAnalysisResult().getSample().setState(result.getState());
					abstractSampleDao.makePersistent(result.getAnalysisResult().getSample());
				}
			}

			session.getTransaction().commit();
		} catch (RuntimeException e) {
			session.getTransaction().rollback();
			throw e;
		} finally {
			session.close();
		}
	}

}
